Best time to buy and sell stock III¶
Time: O(N); Space: O(1); hard
Say you have an array for which the ith element is the price of a given stock on day i.
Design an algorithm to find the maximum profit. You may complete at most two transactions.
Note: You may not engage in multiple transactions at the same time (i.e., you must sell the stock before you buy again).
Example 1:
Input: prices = [3,3,5,0,0,3,1,4]
Output: 6
Explanation:
Buy on day 4 (price = 0) and sell on day 6 (price = 3), profit = 3-0 = 3.
Then buy on day 7 (price = 1) and sell on day 8 (price = 4), profit = 4-1 = 3.
Example 2:
Input: prices = [1,2,3,4,5]
Output: 4
Explanation:
Buy on day 1 (price = 1) and sell on day 5 (price = 5), profit = 5-1 = 4.
Note that you cannot buy on day 1, buy on day 2 and sell them later, as you are engaging multiple transactions at the same time. You must sell before buying again.
Example 3:
Input: prices = [7,6,4,3,1]
Output: 0
Explanation:
In this case, no transaction is done, i.e. max profit = 0.
[1]:
class Solution1(object):
"""
Time: O(N)
Space: O(1)
"""
def maxProfit(self, prices):
"""
:type prices: List[int]
:rtype: int
"""
hold1, hold2 = float("-inf"), float("-inf")
release1, release2 = 0, 0
for i in prices:
release2 = max(release2, hold2 + i)
hold2 = max(hold2, release1 - i)
release1 = max(release1, hold1 + i)
hold1 = max(hold1, -i)
return release2
[2]:
s = Solution1()
prices = [3,3,5,0,0,3,1,4]
assert s.maxProfit(prices) == 6
prices = [1,2,3,4,5]
assert s.maxProfit(prices) == 4
prices = [7,6,4,3,1]
assert s.maxProfit(prices) == 0
[5]:
class Solution2(object):
def maxProfit(self, prices):
"""
:type prices: List[int]
:rtype: int
"""
return self.maxAtMostKPairsProfit(prices, 2)
def maxAtMostKPairsProfit(self, prices, k):
max_buy = [float("-inf") for _ in range(k + 1)]
max_sell = [0 for _ in range(k + 1)]
for i in range(len(prices)):
for j in range(1, min(k, i//2 + 1) + 1):
max_buy[j] = max(max_buy[j], max_sell[j-1] - prices[i])
max_sell[j] = max(max_sell[j], max_buy[j] + prices[i])
return max_sell[k]
[6]:
s = Solution2()
prices = [3,3,5,0,0,3,1,4]
assert s.maxProfit(prices) == 6
prices = [1,2,3,4,5]
assert s.maxProfit(prices) == 4
prices = [7,6,4,3,1]
assert s.maxProfit(prices) == 0
[7]:
class Solution3(object):
def maxProfit(self, prices):
"""
:type prices: List[int]
:rtype: int
"""
min_price, max_profit_from_left, max_profits_from_left = float("inf"), 0, []
for price in prices:
min_price = min(min_price, price)
max_profit_from_left = max(max_profit_from_left, price - min_price)
max_profits_from_left.append(max_profit_from_left)
max_price, max_profit_from_right, max_profits_from_right = 0, 0, []
for i in reversed(range(len(prices))):
max_price = max(max_price, prices[i])
max_profit_from_right = max(max_profit_from_right,
max_price - prices[i])
max_profits_from_right.insert(0, max_profit_from_right)
max_profit = 0
for i in range(len(prices)):
max_profit = max(max_profit,
max_profits_from_left[i] +
max_profits_from_right[i])
return max_profit
[8]:
s = Solution3()
prices = [3,3,5,0,0,3,1,4]
assert s.maxProfit(prices) == 6
prices = [1,2,3,4,5]
assert s.maxProfit(prices) == 4
prices = [7,6,4,3,1]
assert s.maxProfit(prices) == 0
See also:¶
https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii
https://www.lintcode.com/problem/best-time-to-buy-and-sell-stock-iii/description
Related problems:¶
https://leetcode.com/problems/best-time-to-buy-and-sell-stock/
https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/
https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/
https://leetcode.com/problems/maximum-sum-of-3-non-overlapping-subarrays/
https://www.lintcode.com/problem/maximum-subarray
https://www.lintcode.com/problem/maximum-subarray-ii
https://www.lintcode.com/problem/maximum-subarray-iii
https://www.lintcode.com/problem/maximum-subarray-difference
https://www.lintcode.com/problem/best-time-to-buy-and-sell-stock-iii
https://www.lintcode.com/problem/best-time-to-buy-and-sell-stock-v